﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Net;
using System.Xml.Serialization;
using System.Xml;
using System.Globalization;
using System.Security.Cryptography;

namespace winpackman
{
    public class winpackman_class
    {
        public string lastupdate;
        public string updatetime;
        public Dictionary<int, Software> Softwarelist = new Dictionary<int, Software>();
        public Dictionary<String, int> NameToID = new Dictionary<String, int>();
        public Dictionary<int, InstallSoftware> Installlist = new Dictionary<int, InstallSoftware>();
        public Dictionary<String, int> categoryID = new Dictionary<string, int>();
        public Configdata config = new Configdata();

        public Dictionary<string, string> Lang_2toEng = new Dictionary<string, string>();
        public Dictionary<string, string> Lang_Engto2 = new Dictionary<string, string>();

        public string WinPackMan_DataURL = "http://winpackman.mtsgrit.nl/data.php";

        public debugconfig debug = new debugconfig();

        public string OS_Bits;

        public void load()
        {
            if (debug.specialdownload)
                WinPackMan_DataURL = "http://winpackman.mtsgrit.nl/debugdata.php";
            foreach (CultureInfo regio in CultureInfo.GetCultures(CultureTypes.NeutralCultures))
            {
                if (!Lang_2toEng.ContainsKey(regio.TwoLetterISOLanguageName))
                {
                    Lang_2toEng.Add(regio.TwoLetterISOLanguageName, regio.EnglishName);
                    Lang_Engto2.Add(regio.EnglishName, regio.TwoLetterISOLanguageName);
                }
            }
        }

        #region MD5 Generator
        public string GetMD5HashFromFile(string fileName)
        {
            FileStream file = new FileStream(fileName, FileMode.Open);
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] retVal = md5.ComputeHash(file);
            file.Close();

            StringBuilder sb = new StringBuilder();
            for (int i = 0; i < retVal.Length; i++)
            {
                sb.Append(retVal[i].ToString("x2"));
            }
            return sb.ToString();
        }
        #endregion

        #region Random string generator
        public string RandomString(int size, bool lowerCase)
        {
            StringBuilder builder = new StringBuilder();
            Random random = new Random();
            char ch;
            for (int i = 0; i < size; i++)
            {
                ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
                builder.Append(ch);
            }
            if (lowerCase)
                return builder.ToString().ToLower();
            return builder.ToString();
        }
        #endregion

        #region Read/Write config
        public void loadconfig()
        {
            if (File.Exists("Cache/config.xml"))
            {
                Stream stream = File.Open("Cache/config.xml", FileMode.Open, FileAccess.Read);
                XmlSerializer x = new XmlSerializer(config.GetType());
                config = (Configdata)x.Deserialize(stream);
            }
        }

        public void writeconfig()
        {
            Stream stream = File.Open("Cache/config.xml", FileMode.Create, FileAccess.Write);
            XmlSerializer x = new XmlSerializer(config.GetType());
            x.Serialize(stream, config);
            stream.Close();
        }
        #endregion

        #region Remake install list
        public void reloadinstalllist()
        {
            string[] items = new string[Installlist.Count];
            int count = 0;
            foreach (InstallSoftware app in Installlist.Values)
            {
                items[count] = app.MemberOf + ";" + app.Language + ";" + app.Architecture;
                count++;
            }
            Installlist.Clear();
            foreach (string item in items)
            {
                string[] info = item.Split(";".ToCharArray());
                int ID = int.Parse(info[0]);
                Software app = Softwarelist[ID];
                InstallSoftware newItem = new InstallSoftware();
                newItem.Name = app.Name;
                newItem.Language = info[1];
                newItem.MemberOf = ID;
                switch (info[2])
                {
                    case "x86":
                        newItem.install = app.x86.Language[info[1]];
                        break;
                    case "x64":
                        newItem.install = app.x64.Language[info[1]];
                        break;
                }
                Installlist.Add(ID, newItem);
            }

        }
        #endregion
    }

    
    public class Software
    {
        #region Software structure
        public String packageID = "";
        public String categoryID = "";
        public String Name = "";
        public String Version = "";
        public String Description = "";
        public String filetype = "";
        public String VersionType = ""; //normal = ""
        public int[] Dependency = {0};
        public String Installed = "";

        public InstallArchitecture x86 = new InstallArchitecture();
        public InstallArchitecture x64 = new InstallArchitecture();
    }
    public class InstallArchitecture
    {
        public bool available = false;
        public Dictionary<String, InstallLanguage> Language = new Dictionary<String, InstallLanguage>();
    }
    public class InstallLanguage
    {
        public String URL = "";
        public String Arguments = "";
        public String MD5 = "";
        public String Filename = "";
        #endregion
    }

    public class InstallSoftware
    {
        public int MemberOf = 0;
        public String Name = "";
        public String Architecture = "";
        public String Language = "";

        public InstallLanguage install = new InstallLanguage();

        public String Status = "Waiting";
        public int DownloadPercentage = 0;
        public int InstallPercentage = 0;
    }

    public class Configdata
    {
        #region Config structure
        public bool clearcache = true;
        public bool hidex86 = true;
        public bool clearqueryinstall = true;
        public bool viewbeta = false;
        public string[] Language = {"en"};
        #endregion
    }

    public class debugconfig
    {
        public bool specialdownload = false;
        public bool downloadonly = false;
        public bool md5out = false;
    }
}
